package com.fingard.dsp.bank.directbank.unionpay01;

import java.util.Date;

import com.fingard.constant.Format;
import com.fingard.crypto.SignVerifyHelper;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.dsp.bank.directbank.unionpay01.util.GZipUtil;
import com.fingard.dsp.bank.directbank.unionpay01.util.HttpUtils;
import com.fingard.dsp.bank.directbank.unionpay01.util.UlpayRaTools;
import com.fingard.text.StringHelper;
import com.fingard.util.TransIDHelper;
import com.fingard.xml.XmlTextWriter;

public class UnionPay01Base extends DirectBase {
	private static TransIDHelper idHelper = new TransIDHelper(1, 999);

    protected String getQryTransID() {
        Date tmpDateNow = new Date();
        return Format.DateTime12Year2Format.format(tmpDateNow) + idHelper.getNextIDStr();
    }

    protected String getCharset() {
        return getBankConfig().getCharset("UTF-8");
    }
    
    protected void writeCommonHeader(XmlTextWriter xmlWriter, UnionPay01Header tmpBankHeader) {
        xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");
        xmlWriter.writeStartElement("AIPG");
        
        xmlWriter.writeStartElement("INFO");
        xmlWriter.writeElementString("TRX_CODE", tmpBankHeader.transCode);
        if (UnionPay01TransCode.batPayQry_1998_198801.equals(tmpBankHeader.transCode)) {
        	xmlWriter.writeElementString("VERSION", "2.0");
        } else {
        	xmlWriter.writeElementString("VERSION", "2.1");
        }
        xmlWriter.writeElementString("DATA_TYPE", "0");
        xmlWriter.writeElementString("REQ_SN", tmpBankHeader.reqSeqID);
        xmlWriter.writeElementString("SIGNED_MSG", "");
        xmlWriter.writeEndElement();
    }
    
    protected String[] sendToBank(String p_reqStr, ActSetItem actItem, String p_for) throws Exception {
    	String[] tmpStrRet = new String[]{"",""};
    	String submitUrl = bankFront.getUrl(p_for);
		WriteBankLogLn("2.提交银行的地址：" + submitUrl);
		
		String signData = p_reqStr;
		signData = signData.replaceAll("<SIGNED_MSG />", "<SIGNED_MSG></SIGNED_MSG>");
		WriteBankLogLn("签名前原始数据:\r\n" + signData);
		String sign = UlpayRaTools.addSignatrue(signData, actItem);
		WriteBankLogLn("签名结果:" + sign);
		p_reqStr = p_reqStr.replaceAll("<SIGNED_MSG />", sign);
		WriteBankLogLn("签名后发送银行请求数据:\r\n" + p_reqStr);
		// 加压加密
		String Base64 = GZipUtil.gzipString(p_reqStr);
		WriteBankLogStep2(Base64);
		// 通讯使用HTTPS进行通讯
		String response = HttpUtils.sendPostMessage(Base64, submitUrl, getCharset());
		WriteBankLogStep3(response);
		
		if (StringHelper.isNullOrEmpty(response)) {
			tmpStrRet[0] = "-1";
			tmpStrRet[1] = "银行响应为空"; 
			return tmpStrRet;
		}
		
		String tmpRetStr = GZipUtil.ungzipString(response);
		WriteBankLogLn("解压后响应报文明文:\r\n" + tmpRetStr);
		return new String[] { "", tmpRetStr };
	}
    
    protected String signMessage(String p_toSignStr, ActSetItem actItem){
		StringBuilder p_sbLog = new StringBuilder();
		
		try {
			byte[] toSignByte = p_toSignStr.getBytes(getCharset());
			byte[] signResult = SignVerifyHelper.signData(toSignByte, "PKCS12", "SHA1withRSA", actItem.ownKeyStorePath, actItem.ownKeyPassword, p_sbLog);
			if(signResult != null && p_sbLog.length() == 0){
				byte[] sign_asc = new byte[signResult.length * 2];
				hex2Ascii(signResult.length, signResult, sign_asc);
	            return new String(sign_asc, getCharset());
			} else {
				return null;
			}
		} catch (Exception ex) {
			p_sbLog.append(ex.getMessage());
		}
		
		return null;
	}
	
	private void hex2Ascii(int len, byte[] data_in, byte[] data_out)
    {
        byte[] temp1 = new byte[1];
        byte[] temp2 = new byte[1];
        int i = 0; for (int j = 0; i < len; ++i)
        {
            temp1[0] = data_in[i];
            temp1[0] = (byte)(temp1[0] >> 4);
            temp1[0] = (byte)(temp1[0] & 0xF);
            temp2[0] = data_in[i];
            temp2[0] = (byte)(temp2[0] & 0xF);
            if ((temp1[0] >= 0) && (temp1[0] <= 9))
                data_out[j] = (byte)(temp1[0] + 48);
            else if ((temp1[0] >= 10) && (temp1[0] <= 15))
            {
                data_out[j] = (byte)(temp1[0] + 87);
            }

            if ((temp2[0] >= 0) && (temp2[0] <= 9))
                data_out[(j + 1)] = (byte)(temp2[0] + 48);
            else if ((temp2[0] >= 10) && (temp2[0] <= 15))
                data_out[(j + 1)] = (byte)(temp2[0] + 87);

            j += 2;
        }
    }
}
